﻿/*
 * Criado por SharpDevelop.
 * Usuário: Administrador
 * Data: 31/8/2009
 * Hora: 20:52
 *
 * Para alterar este modelo use Ferramentas | Opções | Codificação | Editar Cabeçalhos Padrão.
 */

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows.Forms;

namespace SVM_Sharp
{
    /// <summary>
    /// Description of MainForm.
    /// </summary>
    public partial class MainForm : Form
    {
        private static SVM_SharpCtrl m_mainController = null;

        private static void InitializeControllers()
        {
            m_mainController = new SVM_SharpCtrl();
        }

        private FormEditParameters formParameters = null;
        private FormConfusionMatrix formConfusionMatrix = null;

        private void InitializeForms()
        {
            formParameters = new FormEditParameters();
            formParameters.TopLevel = false;
            formParameters.Location = new Point(30, 325);
            formParameters.FormBorderStyle = FormBorderStyle.None;
            formParameters.Visible = true;
            this.Controls.Add(formParameters);

            formConfusionMatrix = new FormConfusionMatrix();
            formConfusionMatrix.TopLevel = false;
            formConfusionMatrix.Location = new Point(425, 325);
            formConfusionMatrix.FormBorderStyle = FormBorderStyle.None;
            formConfusionMatrix.Visible = true;
            this.Controls.Add(formConfusionMatrix);
            //bt_classify.Enabled = false;
        }

        private bool enableWrite = true;

        public MainForm()
        {
            InitializeControllers();

            //
            // The InitializeComponent() call is required for Windows Forms designer support.
            //
            InitializeComponent();

            //
            // TODO: Add constructor code after the InitializeComponent() call.
            //
            InitializeForms();
        }

        /**
                Início dos procedimentos e eventos associados.
         **/

        private System.Threading.Thread threadScaleTrain,
                                threadScalePredict,
                                threadTrain,
                                threadPredict,
                                threadManagedTests;

        private long m_lastElapsedTimeTrain;
        private long m_lastElapsedTimePredict;

        private void DataGridView2RowHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            for (int i = 0; i < dataGridView2.Columns.Count; ++i)
            {
                dataGridView2.Rows[0].Cells[i].Selected = false;
                bool current = (bool)dataGridView2.Rows[0].Cells[i].Value;
                dataGridView2.Rows[0].Cells[i].Value = !current;
                dataGridView2.Rows[0].Cells[i].Selected = true;

                //System.Diagnostics.Debug.WriteLine(String.Format("Valor coluna {0} é {1}",i, dataGridView2.Rows[0].Cells[i].Value));
            }

            label1.Focus();
            dataGridView2.Focus();
        }

        /// <summary>
        /// Tenta ler arquivo treino no formato LIBSVM. Tenta gerar modelo de parâmetros com dados escolhidos pelo usuário.
        /// Tenta escalonar arquivo treino se opção marcada pelo usuário. Gera arquivo modelo para usar na classificação.
        /// </summary>
        private void Learn()
        {
            entradaDeDadosLearn();
            prepararEexecutarLearn();

            habilitaBotoes(true);
        }

        private void entradaDeDadosLearn()
        {
            int[] listaColunasOff = obterColunasDesabilitadas();
            m_mainController.atribuirListaColunasDesabilitadas(listaColunasOff);
            try
            {
                m_mainController.lerArquivo(txt_treino.Text, SVM_SharpCtrl.ID_TREINO);
                if (dataGridView2.ColumnCount == 0)
                {
                    if (dataGridView2.InvokeRequired)
                    {
                        preencherGridDadosDelegate preencherGridDadosDelegate = new preencherGridDadosDelegate(preencherGridDados);
                        dataGridView2.Invoke(preencherGridDadosDelegate, new object[] { listaColunasOff });
                    }
                    else
                    {
                        preencherGridDados(listaColunasOff);
                    }
                }
            }
            catch (System.Exception x)
            {
                System.Windows.Forms.MessageBox.Show(this, "Erro no arquivo treino:\n " + x, "Erro", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
                return;
            }
        }

        private void preencherParametros()
        {
            if (CtrlTestManager.modoGerenciadorLigado())
            {
                try
                {
                    m_mainController.preencherParametros(CtrlTestManager.obterParametrosAtual());
                }
                catch (ParameterError pe)
                {
                    System.Windows.Forms.MessageBox.Show(this, pe.m_str, "Erro", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
                }

                return;
            }

            try
            {
                m_mainController.preencherParametros(formParameters);
            }
            catch (ParameterError pe)
            {
                System.Windows.Forms.MessageBox.Show(this, pe.m_str, "Erro", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
            }
        }

        private bool isScale()
        {
            if (CtrlTestManager.modoGerenciadorLigado())
            {
                return CtrlTestManager.obterParametrosAtual().getScale();
            }
            else
                return formParameters.IsScaleCheckd();
        }

        private void scaleLearn()
        {
            threadScaleTrain = null;
            m_mainController.executarComputeRange(SVM_SharpCtrl.ID_TREINO);
            Tuple<int, String> par = new Tuple<int, String>(SVM_SharpCtrl.ID_TREINO, "train_scaled.txt");
            threadScaleTrain = new Thread(doScale);
            threadScaleTrain.Start(par);
        }

        private void train()
        {
            threadTrain = null;
            threadTrain = new Thread(doTrain);
            threadTrain.Start();
        }

        private void prepararEexecutarLearn()
        {
            preencherParametros();
            m_mainController.resetarScale();
            if (isScale())
            {
                try
                {
                    scaleLearn();
                }
                catch (System.Exception x)
                {
                    System.Windows.Forms.MessageBox.Show(this, "Erro no escalonamento do arquivo treino:\n " + x, "Erro", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
                    return;
                }
            }
            try
            {
                train();
            }
            catch (System.Exception x)
            {
                System.Windows.Forms.MessageBox.Show(this, "Erro no treinamento:\n " + x, "Erro", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
                return;
            }
        }

        /// <summary>
        /// Tenta ler arquivo de testes no formato do LIBSVM. Escalona arquivo de treino se opção for selecionada. Tenta fazer a predição
        /// com os arquivos escolhidos e com o modelo gerado, retornando no array resultados[]. Gera Matriz de Confusão.
        /// </summary>
        private void Classify()
        {
            entradaDeDadosClassify();
            scaleClassify();
            predict();
        }

        private void entradaDeDadosClassify()
        {
            try
            {
                m_mainController.lerArquivo(txt_teste.Text, SVM_SharpCtrl.ID_TESTE);
            }
            catch (System.Exception x)
            {
                System.Windows.Forms.MessageBox.Show(this, "Erro no arquivo teste:\n " + x, "Erro", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
                return;
            }
        }

        private void scaleClassify()
        {
            threadScalePredict = null;
            if (m_mainController.estaTreinoScaled())
            {
                try
                {
                    Tuple<int, String> par = new Tuple<int, String>(SVM_SharpCtrl.ID_TESTE, "test_scaled.txt");

                    threadScalePredict = new Thread(doScale);
                    threadScalePredict.Start(par);
                }
                catch (System.Exception x)
                {
                    System.Windows.Forms.MessageBox.Show(this, "Erro no escalonamento do arquivo teste:\n " + x, "Erro", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
                    return;
                }
            }
        }

        private void predict()
        {
            threadPredict = null;
            m_mainController.resetarResultados();
            try
            {
                threadPredict = new Thread(doPredict);
                threadPredict.Start();
            }
            catch (System.Exception x)
            {
                System.Windows.Forms.MessageBox.Show(this, "Erro na classificação:\n " + x, "Erro", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
                return;
            }
        }

        /// <summary>
        /// Preenche a grid com o arquivo de treinamento para seleção das colunas a serem efetivamente treinadas.
        /// </summary>
        private void preencherGridDados(int[] _lista)
        {
            System.Collections.Generic.List<int> lista = new System.Collections.Generic.List<int>(_lista);

            dataGridView2.Columns.Clear();

            for (int i = 0; i < m_mainController.obterMaxIndex(SVM_SharpCtrl.ID_TREINO); ++i)
            {
                dataGridView2.Columns.Add(new DataGridViewCheckBoxColumn(false));
                dataGridView2.Columns[i].HeaderText = (i + 1).ToString();
            }

            dataGridView2.Rows.Add();
            for (int i = 0; i < dataGridView2.Rows[0].Cells.Count; ++i)
            {
                dataGridView2.Rows[0].Cells[i].Value = !lista.Contains(i + 1);
            }

            dataGridView2.AllowUserToAddRows = false;

            dataGridView2.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader;
            var hScrollbar = dataGridView2.Controls.OfType<HScrollBar>().First();
            if (!hScrollbar.Visible) // Se nao tiver horizontalScrollBar, da fill
            {
                dataGridView2.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
                dataGridView2.Rows[0].Height += dataGridView2.Height - (dataGridView2.Rows[0].Height + dataGridView2.ColumnHeadersHeight);
            }

            dataGridView2.Update();
        }

        /// <summary>
        /// Salva parâmetros utilizados(nomes dos arquivos, kernel, C, Weights, gamma,coef0,degree) e resultados (accuracys)
        /// em nova entrada do DataSet. Não podem haver itens repetidos (constraints do dataset).
        /// </summary>
        private void salva_resultado()
        {
            System.Data.DataRow tmprow = dsResultados.Tables[0].NewRow();
            m_mainController.preencherResultados(ref tmprow);
            tmprow[SVM_SharpCtrl.ID_SCALED] = isScale();
            tmprow[SVM_SharpCtrl.ID_TREINO_FILE] = txt_treino.Text;
            tmprow[SVM_SharpCtrl.ID_TESTE_FILE] = txt_teste.Text;
            tmprow[SVM_SharpCtrl.ID_OFF_LABELS] = obterColunasDesabilitadasStr();
            tmprow[SVM_SharpCtrl.ID_TRAIN_TIME] = m_lastElapsedTimeTrain;
            tmprow[SVM_SharpCtrl.ID_PREDI_TIME] = m_lastElapsedTimePredict;

            try
            {
                dsResultados.Tables[0].Rows.Add(tmprow);
                dgvResultados.FirstDisplayedScrollingRowIndex = dgvResultados.RowCount - 1;
            }
            catch (System.Exception x)
            {
                atualizarStatus("Resultado já existe.", true);
                System.Diagnostics.Debug.WriteLine("Erro ao salvar classificação:\n " + x.ToString());
                //System.Forms.MessageBox.Show(this, "Erro ao salvar classificação:\n " + x, "Erro", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
                return;
            }

            colorirExtremos();
            atualizarStatus("Resultados salvos.", true);
        }

        private void colorirExtremos()
        {
            double dMin = double.MaxValue;
            double dMax = double.MinValue;
            int nMin = 0;
            int nMax = 0;
            int nConta = 0;
            foreach (System.Data.DataRow row in dsResultados.Tables[0].Rows)
            {
                double dValue = obterValorCelula(row, SVM_SharpCtrl.ID_ACCURACY);

                if (dValue < dMin)
                {
                    dMin = dValue;
                    nMin = nConta;
                }

                if (dValue > dMax)
                {
                    dMax = dValue;
                    nMax = nConta;
                }

                for (int cell = SVM_SharpCtrl.ID_ACCURACY; cell <= SVM_SharpCtrl.ID_ACCURACY + 2; ++cell)
                    dgvResultados.Rows[nConta].Cells[cell].Style.BackColor = Color.White;

                ++nConta;
            }
            for (int cell = SVM_SharpCtrl.ID_ACCURACY; cell <= SVM_SharpCtrl.ID_ACCURACY + 2; ++cell)
                dgvResultados.Rows[nMax].Cells[cell].Style.BackColor = Color.LightGreen;

            for (int cell = SVM_SharpCtrl.ID_ACCURACY; cell <= SVM_SharpCtrl.ID_ACCURACY + 2; ++cell)
                dgvResultados.Rows[nMin].Cells[cell].Style.BackColor = Color.LightPink;
        }

        private double obterValorCelula(System.Data.DataRow row, int cellId)
        {
            string strAcc = row[cellId].ToString();
            strAcc = strAcc.Trim('%');
            strAcc = strAcc.Trim();
            return double.Parse(strAcc);
        }

        /// <summary>
        /// Salva resultados gravados no DataSet para arquivo XML.
        /// </summary>
        private void Exporta_resultados()
        {
            if (sfd_exportar.ShowDialog() != DialogResult.OK)
                return;
            dsResultados.WriteXml(sfd_exportar.FileName);
            txt_status.Text = "Resultados exportados.";
        }

        /// <summary>
        /// Limpa DataSet e carrega resultados de arquivo XML no DataSet.
        /// </summary>
        private void Importa_resultados()
        {
            if (System.Windows.Forms.MessageBox.Show("Quer remover os resultados atuais?", "Importar", MessageBoxButtons.YesNo) == DialogResult.Yes)
                dsResultados.Tables[0].Clear();

            if (ofd_importar.ShowDialog() != DialogResult.OK)
                return;

            try
            {
                dsResultados.ReadXml(ofd_importar.FileName);
                colorirExtremos();
            }
            catch (System.Exception x)
            {
                System.Windows.Forms.MessageBox.Show(this, "Erro ao importar resultados:\n " + x, "Erro", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
                return;
            }

            txt_status.Text = "Resultados importados.";
        }

        /// <summary>
        /// Carrega linha do DataSet para Matriz de Confusão e parâmetros utilizados. Deve-se treinar novamente para que modelo possa
        /// ter os parâmetros carregados.
        /// </summary>
        private void Carrega_resultados()
        {
            int i;
            try
            {
                i = dgvResultados.SelectedRows[0].Index;

                System.Data.DataRow tmprow = dsResultados.Tables[0].NewRow();
                tmprow = dsResultados.Tables[0].Rows[i];
                formParameters.Carrega_resultados(tmprow);
                m_mainController.atribuirResultados((double[])tmprow[SVM_SharpCtrl.ID_RESULTADOS]);
                m_mainController.preencherMatrizConfusao(formConfusionMatrix);
                atribuirColunasDesabilitadas(System.Convert.ToString(tmprow[SVM_SharpCtrl.ID_OFF_LABELS]));
                txt_treino.Text = System.Convert.ToString(tmprow[SVM_SharpCtrl.ID_TREINO_FILE]);
                txt_teste.Text = System.Convert.ToString(tmprow[SVM_SharpCtrl.ID_TESTE_FILE]);
                txt_status.Text = "Resultados carregados.";
            }
            catch (System.Exception x)
            {
                System.Windows.Forms.MessageBox.Show(this, "Erro ao carregar resultados:\n " + x, "Erro", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
                return;
            }
        }

        private void abrirArqTreino()
        {
            if (ofd_treino.ShowDialog() != DialogResult.OK)
                return;

            txt_treino.Text = ofd_treino.FileName;

            try
            {
                m_mainController.lerArquivo(txt_treino.Text, SVM_SharpCtrl.ID_TREINO);
                dataGridView2.Columns.Clear();
                preencherGridDados(obterColunasDesabilitadas());
            }
            catch (System.Exception x)
            {
                System.Windows.Forms.MessageBox.Show(this, "Erro no arquivo treino:\n " + x, "Erro", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
                return;
            }
        }

        private void abrirArqTeste()
        {
            if (ofd_teste.ShowDialog() != DialogResult.OK)
                return;

            txt_teste.Text = ofd_teste.FileName;
        }

        private void abrirArqSaida()
        {
            if (sfd_saida.ShowDialog() != DialogResult.OK)
                return;

            txt_saida.Text = sfd_saida.FileName;
        }

        private void Bt_learnClick(object sender, System.EventArgs e)
        {
            Learn();
        }

        private void Bt_classifyClick(object sender, System.EventArgs e)
        {
            Classify();
        }

        private void btn_carregar_Click(object sender, System.EventArgs e)
        {
            Carrega_resultados();
        }

        private void button2_Click(object sender, System.EventArgs e)
        {
            Importa_resultados();
        }

        private void button3_Click(object sender, System.EventArgs e)
        {
            Exporta_resultados();
        }

        private void dataGridView1_DoubleClick(object sender, System.EventArgs e)
        {
            Carrega_resultados();
        }

        private void dataGridView1_DoubleClick_1(object sender, System.EventArgs e)
        {
            Carrega_resultados();
        }

        private void Bt_learneclasClick(object sender, System.EventArgs e)
        {
            Learn();
            Classify();
        }

        private void sobreToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            AboutBox1 about = new AboutBox1();
            about.ShowDialog(this);
        }

        private void sairToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            Dispose();
        }

        private int[] obterColunasDesabilitadas()
        {
            System.Collections.ArrayList listaColunasOff = new System.Collections.ArrayList();
            for (int i = 0; i < dataGridView2.Columns.Count; ++i)
            {
                if (dataGridView2.Rows[0].Cells[i].Value.Equals(false))
                    listaColunasOff.Add(i + 1);
            }

            return (int[])listaColunasOff.ToArray(typeof(int));
        }

        private String obterColunasDesabilitadasStr()
        {
            int[] r = obterColunasDesabilitadas();
            String sr = "";
            foreach (var ir in r)
            {
                sr += String.Format("{0};", ir);
            }
            return sr;
        }

        private void doTrain()
        {
            try
            {
                if (threadPredict != null)
                    while (threadPredict.IsAlive) ;

                if (threadScaleTrain != null)
                    while (threadScaleTrain.IsAlive) ;

                habilitaBotoes(false);
                atualizarStatus("Aprendendo modelo...");
                System.Diagnostics.Stopwatch stopW = new System.Diagnostics.Stopwatch();
                stopW.Reset();
                stopW.Start();
                m_mainController.executarTreino();
                stopW.Stop();
                if (enableWrite)
                    m_mainController.escreverModel();
                m_lastElapsedTimeTrain = stopW.ElapsedMilliseconds;
                atualizarStatus(string.Format("Modelo aprendido - {0} ms", m_lastElapsedTimeTrain));
            }
            catch (System.Exception x)
            {
                atualizarStatus("Erro no treinamento");
                mostrarErro("Erro no treinamento:\n " + x);
            }
            habilitaBotoes(true);
        }

        private void doPredict()
        {
            try
            {
                if (threadTrain != null)
                    while (threadTrain.IsAlive) ;

                if (threadScalePredict != null)
                    while (threadScalePredict.IsAlive) ;

                habilitaBotoes(false);
                atualizarStatus("Classificação iniciada...");
                System.Diagnostics.Stopwatch stopW = new System.Diagnostics.Stopwatch();
                stopW.Reset();
                stopW.Start();
                m_mainController.executarPredict(txt_saida.Text);
                stopW.Stop();
                Gera_matriz_conf_assync();
                m_lastElapsedTimePredict = stopW.ElapsedMilliseconds;
                atualizarStatus(string.Format("Classificação terminada - {0} ms", m_lastElapsedTimePredict));
                Salva_resultado_assync();
            }
            catch (System.Exception x)
            {
                atualizarStatus("Erro na classificação");
                mostrarErro("Erro na classificação:\n " + x);
            }
            habilitaBotoes(true);
        }

        private void doScale(object param)
        {
            try
            {
                Tuple<int, String> tupla = (Tuple<int, String>)param;
                m_mainController.executarScale(tupla.Item1);

                if (enableWrite)
                    m_mainController.escreverSaida(tupla.Item1, tupla.Item2);
            }
            catch (System.Exception x)
            {
                atualizarStatus("Erro no escalonamento");
                mostrarErro("Erro no escalonamento do arquivo teste:\n " + x);
            }
        }

        private delegate void atualizarStatusDelegate(string _text, bool _bAppend = false);

        private delegate void habilitaBotoesDelegate(bool _val);

        private delegate void habilitaBotaoDelegate(Button botao, bool _val);

        private delegate void Gera_matriz_confDelegate();

        private delegate void Salva_resultadoDelegate();

        private delegate void mostrarErroDelegate(string _text);

        private delegate void preencherGridDadosDelegate(int[] _listaColunasOff);

        private delegate void atualizarGridViewDelegate();

        private void mostrarErro(string _text)
        {
            if (InvokeRequired)
            {
                mostrarErroDelegate erroDelegate = new mostrarErroDelegate(mostrarErro);
                Invoke(erroDelegate, new object[] { _text });
            }
            else
            {
                System.Windows.Forms.MessageBox.Show(this, _text, "Erro", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
            }
        }

        private void Gera_matriz_conf_assync()
        {
            if (formConfusionMatrix.InvokeRequired)
            {
                Gera_matriz_confDelegate geraMatrizDelegate = new Gera_matriz_confDelegate(Gera_matriz_conf_assync);
                bt_classify.Invoke(geraMatrizDelegate);
            }
            else
            {
                m_mainController.preencherMatrizConfusao(formConfusionMatrix);
            }
        }

        private void Salva_resultado_assync()
        {
            if (dgvResultados.InvokeRequired)
            {
                Salva_resultadoDelegate salvaResultadoDelegate = new Salva_resultadoDelegate(Salva_resultado_assync);
                dgvResultados.Invoke(salvaResultadoDelegate);
            }
            else
            {
                salva_resultado();
            }
        }

        private void habilitaBotoes(bool _val)
        {
            if (btPararTestes.Visible == true)
                return;

            if (bt_classify.InvokeRequired)
            {
                habilitaBotoesDelegate updateButtons = new habilitaBotoesDelegate(habilitaBotoes);
                bt_classify.Invoke(updateButtons, new object[] { _val });
            }
            else
            {
                bt_classify.Enabled = _val;
                bt_learn.Enabled = _val;
                bt_learneclas.Enabled = _val;
                formParameters.chkMultiThread.Enabled = _val;
            }
        }

        private void habilitaBotao(Button botao, bool _val)
        {
            if (bt_classify.InvokeRequired)
            {
                habilitaBotaoDelegate updateButton = new habilitaBotaoDelegate(habilitaBotao);
                botao.Invoke(updateButton, new object[] { botao, _val });
            }
            else
            {
                botao.Visible = _val;
            }
        }

        private void atualizarStatus(string _strStatus, bool _bAppend = false)
        {
            if (txt_status.InvokeRequired)
            {
                atualizarStatusDelegate updateTextDelegate = new atualizarStatusDelegate(atualizarStatus);
                txt_status.Invoke(updateTextDelegate, new object[] { _strStatus, _bAppend });
            }
            else
            {
                if (_bAppend)
                    txt_status.Text += " - " + _strStatus;
                else
                    txt_status.Text = _strStatus;
            }
        }

        private void colunasToolStripMenuItem_Click(object sender, EventArgs e)
        {
        }

        private void ParametrosToolStripMenuItemClick(object sender, EventArgs e)
        {
        }

        private void graficoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //FormPlotData plot = new FormPlotData();
            //plot.gerar(treino);
            //plot.Show();
        }

        private void atribuirColunasDesabilitadas(String tmprow)
        {
            List<int> lista = new List<int>();
            foreach (var data in tmprow.Split(';'))
            {
                try
                {
                    int nData = int.Parse(data);
                    lista.Add(nData);
                }
                catch (Exception ex)
                {
                    continue;
                }
            }

            System.Collections.ArrayList listaColunasOff = new System.Collections.ArrayList();
            for (int i = 0; i < dataGridView2.Columns.Count; ++i)
            {
                dataGridView2.Rows[0].Cells[i].Value = lista.IndexOf(i + 1) == -1;
            }

            bt_classify.Enabled = false;
        }

        private void parameterSelectionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            m_mainController.parameterSelection();
            m_mainController.preencherParametros(formParameters);
        }

        private void testManagerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            GerenciadorTestes gerenciador = new GerenciadorTestes();
            gerenciador.ShowDialog();

            if (CtrlTestManager.modoGerenciadorLigado())
                initTests();
        }

        private void importDataToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FormImportData f = new FormImportData();
            f.Show();
        }

        private void atualizaGridView()
        {
            dgvResultados.Invalidate();
        }

        private void doTests()
        {
            enableWrite = false;
            for (int i = 0; i < CtrlTestManager.obterNumTestes(); ++i)
            {
                Learn();
                Classify();

                if (threadPredict != null)
                    while (threadPredict.IsAlive) ;

                CtrlTestManager.imcrementarParametrosAtual();
            }

            finalizarTestes();
        }

        private void finalizarTestes()
        {
            CtrlTestManager.resetarParametrosAtual();
            enableWrite = true;

            atualizarGridViewDelegate delegateDGVInvalidate = new atualizarGridViewDelegate(atualizaGridView);
            dgvResultados.Invoke(delegateDGVInvalidate);

            habilitaBotao(btPararTestes, false);
            habilitaBotoes(true);
        }

        public void initTests()
        {
            habilitaBotoes(false);
            btPararTestes.Visible = true;
            threadManagedTests = new Thread(doTests);
            threadManagedTests.Start();
        }

        private void abrirTreinoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            abrirArqTreino();
        }

        private void abrirTesteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            abrirArqTeste();
        }

        private void abrirSaidaToolStripMenuItem_Click(object sender, EventArgs e)
        {
            abrirArqSaida();
        }

        private void Bt_treinoClick(object sender, System.EventArgs e)
        {
            abrirArqTreino();
        }

        private void Bt_testeClick(object sender, System.EventArgs e)
        {
            abrirArqTeste();
        }

        private void Bt_saidaClick(object sender, System.EventArgs e)
        {
            abrirArqSaida();
        }

        private void run_cmd()
        {
            ProcessStartInfo start = new ProcessStartInfo();
            start.FileName = "C:\\Python27\\pythonw.exe";
            start.Arguments = string.Format("C:\\Users\\alexandre\\Desktop\\TCC\\SVM\\SVM_Sharp\\SVM_Sharp\\files\\te\\matlabTest.py -t {0} -o C:/Users/alexandre/Desktop/TCC/SVM/SVM_Sharp/SVM_Sharp/files/te/out.txt", txt_teste.Text);
            start.UseShellExecute = false;
            start.RedirectStandardOutput = true;
            using (Process process = Process.Start(start))
            {
                using (StreamReader reader = process.StandardOutput)
                {
                    string result = reader.ReadToEnd();
                    Console.Write(result);
                }
            }
        }

        private void rodarScript()
        {
            run_cmd();
        }

        private void btPararTestes_Click(object sender, EventArgs e)
        {
            if (threadManagedTests.IsAlive)
            {
                threadManagedTests.Abort();
                finalizarTestes();
            }
        }
    }
}